package lambda;

import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.IntStream;

public class Lambda1 {

    String s = "Good";

//    start is local variable
//    Supplier incrementer(int start) {
//        s+=s;
//        return () -> start++;
//
//    }

//    new test

    //简单地说，它是关于存储成员变量的位置。局部变量在堆栈上，但是成员变量在堆上。
    // 因为我们处理的是堆内存，所以编译器可以保证lambda可以访问start的最新值。
    private int start = 0;

    //    while start is a instance variable
    Supplier incrementer() {
        return () -> start++;
    }

    public int workaroundSingleThread() {
        int[] holder = new int[] { 2 };

        IntStream sums = IntStream
                .of(1, 2, 3)
//                你以为是对每个值加2？实际上是加0，因为holder的最新值是0而非2
                .map(val -> val + holder[0]);
        holder[0] = 0;

        return sums.sum();
    }



    public void workaroundMultithreading() {
        int[] holder = new int[] { 2 };


//这里的和是多少?这取决于我们的模拟处理需要多长时间。如果模拟处理足够短
// 让方法的执行在另一个线程执行之前终止，它将输出6，否则，它将输出12。
//一般来说，这类变通方法容易出错，并且会产生不可预知的结果，所以我们应该避免使用它们。
        Runnable runnable = () -> System.out.println(IntStream
                .of(1, 2, 3)
                .map(val -> val + holder[0])
                .sum());
//        System.out.println(new Thread(runnable).getName());     //Thread-0

        //所以这个是Thread-1，那么就有Thread-1线程和main线程
        new Thread(runnable).start();

//        System.out.println(new Thread(runnable).getName());     //Thread-2
//        System.out.println(new Thread(runnable).getName());     //Thread-3

//        System.out.println(Thread.currentThread().getName());
        // simulating some processing
        //模拟一些处理，sleep作用的对象是
        try {
            //sleep休眠的是【当前线程】
            Thread.sleep(new Random().nextInt(3) * 1000L);
            System.out.println(Thread.currentThread().getName());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        holder[0] = 0;
    }


    public static void main(String[] args) {
//        System.out.println(new Lambda1().workaroundSingleThread());
        new Lambda1().workaroundMultithreading();

    }
}
